package com.meiyuetao.myt.md.web.action;

import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import com.meiyuetao.myt.md.entity.*;
import lab.s2jh.core.annotation.MetaData;
import lab.s2jh.core.pagination.GroupPropertyFilter;
import lab.s2jh.core.pagination.PropertyFilter;
import lab.s2jh.core.pagination.PropertyFilter.MatchType;
import lab.s2jh.core.service.BaseService;
import lab.s2jh.core.service.Validation;
import lab.s2jh.core.web.annotation.SecurityControlIgnore;
import lab.s2jh.core.web.view.OperationResult;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.struts2.rest.HttpHeaders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.meiyuetao.myt.core.web.MytBaseController;
import com.meiyuetao.myt.kuajing.entity.KjHeaderInfo.KjActionTypeEnum;
import com.meiyuetao.myt.kuajing.entity.KjSkuInfo;
import com.meiyuetao.myt.kuajing.service.KjSkuInfoService;
import com.meiyuetao.myt.md.entity.Commodity.SolrFilterTypeEnum;
import com.meiyuetao.myt.md.service.CategoryService;
import com.meiyuetao.myt.md.service.CommodityDistributRegionService;
import com.meiyuetao.myt.md.service.CommodityService;
import com.meiyuetao.myt.md.service.KuajingMessageService;
import com.meiyuetao.myt.md.service.PartnerCategoryService;
import com.meiyuetao.myt.md.service.RecommendFittingService;
import com.meiyuetao.myt.md.service.RegionService;
import com.meiyuetao.myt.partner.entity.Partner;
import com.meiyuetao.myt.partner.service.PartnerService;
import com.meiyuetao.myt.stock.entity.StorageLocation;
import com.meiyuetao.myt.vip.entity.VipCommodity;
import com.meiyuetao.myt.vip.service.VipCommodityService;

@MetaData("CommodityController")
public class CommodityController extends MytBaseController<Commodity, Long> {

    protected final Logger logger = LoggerFactory.getLogger(CommodityController.class);

    @Autowired
    private RecommendFittingService recommendFittingService;

    @Autowired
    protected CommodityService commodityService;

    @Autowired
    private VipCommodityService vipCommodityService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private PartnerService partnerService;

    @Autowired
    private PartnerCategoryService partnerCategoryService;

    @Autowired
    private KuajingMessageService kuajingMessageService;

    @Autowired
    private KjSkuInfoService kjSkuInfoService;

    @Autowired
    protected RegionService regionService;

    @Autowired
    protected CommodityDistributRegionService commodityDistributRegionService;

    private File file;
    private File erpExcel;

    public File getFile() {
        return file;
    }

    public void setFile(File file) {
        this.file = file;
    }

    public HttpHeaders kjNew() {
        KjCommodityInfo kjCommodityInfo = bindingEntity.getKjCommodityInfo();
        kjCommodityInfo.setSku(bindingEntity.getSku());
        kjCommodityInfo.setGoodsName(bindingEntity.getTitle());

        KjSkuInfo kjSkuInfo = new KjSkuInfo(bindingEntity, KjActionTypeEnum.NEW);
        String xml = kuajingMessageService.generateSkuInfoXml(kjSkuInfo);
        if (kuajingMessageService.postMessage(xml)) {
            kjSkuInfo.setXmlStr(xml);
            commodityService.saveThisAndInfo(bindingEntity, kjSkuInfo);
            setModel(OperationResult.buildSuccessResult("新增备案，提交成功"));
        } else {
            setModel(OperationResult.buildWarningResult("新增备案，提交失败！", xml));
        }

        return buildDefaultHttpHeaders();
    }

    public HttpHeaders kjEdit() {
        KjCommodityInfo kjCommodityInfo = bindingEntity.getKjCommodityInfo();
        kjCommodityInfo.setSku(bindingEntity.getSku());
        kjCommodityInfo.setGoodsName(bindingEntity.getTitle());

        KjSkuInfo kjSkuInfo = new KjSkuInfo(bindingEntity, KjActionTypeEnum.EDIT);
        String xml = kuajingMessageService.generateSkuInfoXml(kjSkuInfo);
        if (kuajingMessageService.postMessage(xml)) {
            kuajingMessageService.postMessage(xml);
            kjSkuInfo.setXmlStr(xml);
            commodityService.saveThisAndInfo(bindingEntity, kjSkuInfo);
            setModel(OperationResult.buildSuccessResult("变更备案，提交成功"));
        } else {
            setModel(OperationResult.buildWarningResult("新增备案，提交失败！", xml));
        }

        return buildDefaultHttpHeaders();
    }

    public HttpHeaders kjPause() {
        KjCommodityInfo kjCommodityInfo = bindingEntity.getKjCommodityInfo();
        kjCommodityInfo.setSku(bindingEntity.getSku());
        kjCommodityInfo.setGoodsName(bindingEntity.getTitle());

        KjSkuInfo kjSkuInfo = new KjSkuInfo(bindingEntity, KjActionTypeEnum.PAUSE);
        String xml = kuajingMessageService.generateSkuInfoXml(kjSkuInfo);
        if (kuajingMessageService.postMessage(xml)) {
            kuajingMessageService.postMessage(xml);
            kjSkuInfo.setXmlStr(xml);
            commodityService.saveThisAndInfo(bindingEntity, kjSkuInfo);
            setModel(OperationResult.buildSuccessResult("变更备案，提交成功"));
        } else {
            setModel(OperationResult.buildWarningResult("新增备案，提交失败！", xml));
        }
        return buildDefaultHttpHeaders();
    }

    public HttpHeaders importPage() {
        return buildDefaultHttpHeaders("importPage");
    }

    public HttpHeaders importErpProduct() {
        if (file == null) {
            setModel(OperationResult.buildFailureResult("请选择上传文件"));
            return buildDefaultHttpHeaders();
        }
        String msg = commodityService.importErpProduct(file);
        setModel(OperationResult.buildSuccessResult(msg));
        return buildDefaultHttpHeaders();
    }

    public HttpHeaders erpCommodityUpdate() {
        if (erpExcel == null) {
            setModel(OperationResult.buildFailureResult("请选择上传文件"));
            return buildDefaultHttpHeaders();
        }
        if (StringUtils.isBlank(getParameter("updateType"))) {
            setModel(OperationResult.buildFailureResult("请选择商品同步方式"));
            return buildDefaultHttpHeaders();
        }
        String failErpIds = "";
        try {
            failErpIds = commodityService.erpCommodityUpdate(erpExcel, getParameter("updateType"), getParameter("solrFilterType"));
        } catch (Exception e) {
            setModel(OperationResult.buildFailureResult("excel解析错误"));
            return buildDefaultHttpHeaders();
        }
        if (StringUtils.isNotBlank(failErpIds)) {
            setModel(OperationResult.buildFailureResult(failErpIds));
        } else {
            setModel(OperationResult.buildSuccessResult("成功同步"));
        }
        return buildDefaultHttpHeaders();
    }

    public HttpHeaders getContainSensitiveCommodityList() {
        List<Commodity> commodities = commodityService.findContainSensitiveCommodityList();
        setModel(buildPageResultFromList(commodities));
        return buildDefaultHttpHeaders();
    }

    @Override
    protected BaseService<Commodity, Long> getEntityService() {
        return commodityService;
    }

    @Override
    protected void checkEntityAclPermission(Commodity entity) {
        // 限定只能访问登录用户所在商家的数据
        /*
         * Partner partner = getLogonPartner(); if (partner == null ||
         * (!partner.getCode().equals("0000000000") &&
         * !partner.equals(entity.getPartner()))) { throw new
         * DataAccessDeniedException(); }
         */
    }

    @Override
    protected void appendFilterProperty(GroupPropertyFilter groupPropertyFilter) {
        // 限定只能访问登录用户所在商家的数据
        Partner partner = getLogonPartner();
        if (partner != null && !partner.getCode().equals("0000000000")) {
            groupPropertyFilter.forceAnd(new PropertyFilter(MatchType.EQ, "partner", partner));
        }
    }

    @Override
    public void prepareEdit() {
        super.prepareEdit();
        if (bindingEntity.isNew()) {
            String sku = RandomStringUtils.randomNumeric(8);
            while (commodityService.findBySku(sku) != null) {
                sku = RandomStringUtils.randomNumeric(8);
            }
            bindingEntity.setSku(sku);
        }
    }

    @Override
    protected void setupDetachedBindingEntity(Long id) {
        bindingEntity = getEntityService().findDetachedOne(id, "commodityVaryPrice", "commodityPics", "commodityPrices", "commoditySkuRelations", "vipCommodityRates");
    }

    @Override
    @MetaData("保存")
    public HttpHeaders doSave() {
        if (bindingEntity.isNew()) {
            bindingEntity.setPartner(this.getLogonPartner());
        }
        List<CommodityPic> commodityPics = bindingEntity.getCommodityPics();
        if (commodityPics != null && commodityPics.size() > 0) {
            for (CommodityPic commodityPic : commodityPics) {
                commodityPic.setCommodity(bindingEntity);
            }
            bindingEntity.setSmallPic(commodityPics.get(0).getBigPicUrl());
        }

        // 已不适用
        // // 校验，一个 TmallSKU 只能对应关联一个商品
        // String tmallSku = bindingEntity.getTmallSku();
        // if (StringUtils.isNotBlank(tmallSku)) {
        // Commodity commodity = commodityService.findByProperty("tmallSku",
        // tmallSku);
        // if (commodity != null) {
        // Validation.isTrue(false, "这个tmallSku:[ " + tmallSku + " ]已经关联了商品[ " +
        // commodity.getDisplay()
        // + "]，不可重复关联");
        // }
        // }

        // 商品销售区域 管理
        String[] regionsIds = bindingEntity.getRegionsId().split(",");
        bindingEntity.setCommodityDistributRegion(null);
        Set<CommodityDistributRegion> commDisReSet = new HashSet<CommodityDistributRegion>();
        for (String regionId : regionsIds) {
            if (StringUtils.isEmpty(regionId)) {
                continue;
            }
            Region region = regionService.findOne(Long.valueOf(regionId));
            if (bindingEntity.isNew()) {
                CommodityDistributRegion commodityDistributRegion = new CommodityDistributRegion();
                commodityDistributRegion.setCommodity(bindingEntity);
                commodityDistributRegion.setRegion(region);
                commDisReSet.add(commodityDistributRegion);
                continue;
            }
            GroupPropertyFilter groupPropertyFilter = GroupPropertyFilter.buildDefaultAndGroupFilter();
            groupPropertyFilter.append(new PropertyFilter(MatchType.EQ, "region", region));
            groupPropertyFilter.append(new PropertyFilter(MatchType.EQ, "commodity", bindingEntity));
            List<CommodityDistributRegion> commodityDistributRegions = commodityDistributRegionService.findByFilters(groupPropertyFilter);
            if (!CollectionUtils.isEmpty(commodityDistributRegions)) {
                for (CommodityDistributRegion comm : commodityDistributRegions) {
                    commDisReSet.add(comm);
                }
            } else {
                CommodityDistributRegion commodityDistributRegion = new CommodityDistributRegion();
                commodityDistributRegion.setCommodity(bindingEntity);
                commodityDistributRegion.setRegion(region);
                commDisReSet.add(commodityDistributRegion);
            }
        }
        bindingEntity.setCommodityDistributRegion(commDisReSet);
        return super.doSave();
    }

    @Override
    @MetaData("查询")
    public HttpHeaders findByPage() {
        return super.findByPage();
    }

    @Override
    @MetaData("操作记录")
    public HttpHeaders revisionList() {
        return super.revisionList();
    }

    @Override
    @MetaData("数据对比")
    public HttpHeaders revisionCompare() {
        return super.revisionCompare();
    }

    // TODO
    @MetaData("推荐配件")
    public HttpHeaders recommendFittings() {
        HttpServletRequest request = this.getRequest();
        Long id = Long.valueOf(request.getParameter("id"));
        List<RecommendFitting> lstReFittings = recommendFittingService.findAll(id);
        if (lstReFittings.isEmpty()) {
            RecommendFitting rf = new RecommendFitting();
            lstReFittings.add(rf);
        }
        setModel(lstReFittings);
        return buildDefaultHttpHeaders();
    }

    public Map<String, String> getCategoryLabelsMap() {
        Category category = bindingEntity.getCategory();
        Map<String, String> dataMap = Maps.newLinkedHashMap();
        if (category != null) {
            if (StringUtils.isNotBlank(category.getKeywords())) {
                String[] keywords = category.getKeywords().split(" ");
                for (String keyword : keywords) {
                    if (StringUtils.isNotBlank(keyword)) {
                        dataMap.put(keyword, keyword);
                    }
                }
            }
            if (category.getParent() != null && StringUtils.isNotBlank(category.getParent().getKeywords())) {
                String[] parentKeywords = category.getParent().getKeywords().split(" ");
                for (String parentKeyword : parentKeywords) {
                    if (StringUtils.isNotBlank(parentKeyword)) {
                        dataMap.put(parentKeyword, parentKeyword);
                    }

                }
            }
        }
        if (dataMap.size() == 0) {
            List<Category> categories = categoryService.findLabels();
            Collections.sort(categories);
            for (Category label : categories) {
                dataMap.put(label.getName(), label.getName());
            }
        }
        return dataMap;
    }

    public HttpHeaders doCrawl() {
        String[] urls = this.getRequest().getParameter("url").replaceAll("\n", ",").split(",");
        commodityService.startAsyncCrawl(true, urls);
        setModel(OperationResult.buildSuccessResult("爬虫异步作业进行中……"));
        return buildDefaultHttpHeaders();
    }

    @MetaData(value = "商品的价格计划")
    public HttpHeaders getCommodityPrices() {
        List<CommodityPrice> commodityPrices = bindingEntity.getCommodityPrices();
        setModel(buildPageResultFromList(commodityPrices));
        return buildDefaultHttpHeaders();
    }

    @MetaData(value = "价格计划")
    public HttpHeaders getCommodityPricePlans() {
        List<CommodityPricePlan> commodityPricePlans = bindingEntity.getCommodityPricePlans();
        setModel(buildPageResultFromList(commodityPricePlans));
        return buildDefaultHttpHeaders();
    }

    @MetaData(value = "租借商品价格")
    public HttpHeaders getCommodityRentalPrice() {
        List<CommodityRentalPrice> commodityRentalPrice = bindingEntity.getCommodityRentalPrice();
        setModel(buildPageResultFromList(commodityRentalPrice));
        return buildDefaultHttpHeaders();
    }

    @MetaData(value = "关联外部商品")
    public HttpHeaders getCommoditySkuRelation() {
        List<CommoditySkuRelation> CommoditySkuRelations = bindingEntity.getCommoditySkuRelations();
        setModel(buildPageResultFromList(CommoditySkuRelations));
        return buildDefaultHttpHeaders();
    }

    @MetaData(value = "商品分类")
    public HttpHeaders getCategories() {
        setModel(buildPageResultFromList(partnerCategoryService.findAllSorted(getLogonPartner())));
        return buildDefaultHttpHeaders();
    }

    @MetaData(value = "常用商品数据")
    @SecurityControlIgnore
    public HttpHeaders frequentUsedDatas() {
        Set<Map<String, Object>> datas = Sets.newHashSet();
        Collection<Commodity> commodities = commodityService.findFrequentUsedCommodities();
        for (Commodity commodity : commodities) {
            Map<String, Object> item = Maps.newHashMap();
            item.put("id", commodity.getId());
            item.put("sku", commodity.getSku());
            item.put("barcode", commodity.getBarcode() == null ? "" : commodity.getBarcode());
            item.put("title", commodity.getTitle());
            item.put("display", commodity.getDisplay());
            item.put("measureUnit", commodity.getMeasureUnit());
            StorageLocation storageLocation = commodity.getDefaultStorageLocation();
            if (storageLocation != null) {
                item.put("defaultStorageLocation.id", storageLocation.getId());
                item.put("storageLocation.id", storageLocation.getId());
                item.put("storageLocation.display", storageLocation.getDisplay());
            }
            CommodityVaryPrice commodityVaryPrice = commodity.getCommodityVaryPrice();
            if (commodityVaryPrice != null) {
                item.put("price", commodityVaryPrice.getLastSalePrice());
                item.put("costPrice", commodityVaryPrice.getLastPurchasePrice());
                // Start 代理商配货单创建用到的属性
                item.put("commodity.commodityVaryPrice.level1AgentSalePrice", commodityVaryPrice.getLevel1AgentSalePrice());
                item.put("commodity.commodityVaryPrice.level2AgentSalePrice", commodityVaryPrice.getLevel2AgentSalePrice());
                item.put("commodity.commodityVaryPrice.level3AgentSalePrice", commodityVaryPrice.getLevel3AgentSalePrice());
                // END 代理商配货单创建用到的属性
            }
            if (item.get("lastSalePrice") == null) {
                item.put("price", commodity.getPrice());
            }
            if (item.get("costPrice") == null) {
                item.put("costPrice", commodity.getCostPrice());
            }
            Set<String> keys = Sets.newHashSet(item.keySet());
            for (String key : keys) {
                if (key.indexOf(".") == -1) {
                    item.put("commodity." + key, item.get(key));
                }
            }
            datas.add(item);
        }
        setModel(datas);
        return buildDefaultHttpHeaders();
    }

    public HttpHeaders doClone() {

        String title = this.getRequest().getParameter("title");
        String isCopyPic = this.getRequest().getParameter("isCopyPic");
        String isCopyPrice = this.getRequest().getParameter("isCopyPrice");
        String erpProductId = this.getRequest().getParameter("erpProductId");
        if (StringUtils.isNotBlank(erpProductId)) {
            Commodity commodity = commodityService.findByProperty("erpProductId", erpProductId);
            Validation.isTrue(commodity == null, "erp商品编号:" + erpProductId + "已存在");
        }
        bindingEntity.setErpProductId(erpProductId);
        Commodity newCommodity = commodityService.clone(bindingEntity, title, BooleanUtils.toBoolean(isCopyPic), BooleanUtils.toBoolean(isCopyPrice));
        setModel(OperationResult.buildSuccessResult("克隆成功，新商品的编码：" + newCommodity.getSku()));
        return buildDefaultHttpHeaders();
    }

    public HttpHeaders findByBarcode() {
        String barcode = getRequiredParameter("barcode");
        Commodity commodity = commodityService.findByBarcode(barcode);
        if (commodity == null) {
            setModel(OperationResult.buildFailureResult("未知商品数据: " + barcode));
        } else {
            setModel(commodity);
        }
        return buildDefaultHttpHeaders();
    }

    public HttpHeaders commoditySaleDateCounts() {
        setModel(buildPageResultFromList(bindingEntity.getCommoditySaleDateCounts()));
        return buildDefaultHttpHeaders();
    }

    public HttpHeaders putOnAndRecTrue() {

        if (StringUtils.isNotBlank(getParameter("ids"))) {
            Long[] ids = this.getSelectSids();
            Validation.isTrue(ids != null && ids.length > 0, "至少选择一条记录");
            List<Commodity> commodities = commodityService.findAll(ids);
            for (Commodity commodity : commodities) {
                commodityService.putOnAndRec(commodity, true);
            }
            setModel(OperationResult.buildSuccessResult("上架" + commodities.size() + "条数据，并恢复首页推荐"));
        } else {
            commodityService.putOnAndRec(bindingEntity, true);
            setModel(OperationResult.buildSuccessResult("操作成功：上架并恢复首页推荐"));
        }

        return buildDefaultHttpHeaders();
    }

    public HttpHeaders putOnAndRecFalse() {

        if (StringUtils.isNotBlank(getParameter("ids"))) {
            Long[] ids = this.getSelectSids();
            Validation.isTrue(ids != null && ids.length > 0, "至少选择一条记录");
            List<Commodity> commodities = commodityService.findAll(ids);
            for (Commodity commodity : commodities) {
                commodityService.putOnAndRec(commodity, false);
            }
            setModel(OperationResult.buildSuccessResult("上架" + commodities.size() + "条数据，并忽略首页推荐"));
        } else {
            commodityService.putOnAndRec(bindingEntity, false);
            setModel(OperationResult.buildSuccessResult("操作成功：上架但忽略首页推荐"));
        }

        return buildDefaultHttpHeaders();
    }

    public HttpHeaders putOff() {
        if (StringUtils.isNotBlank(getParameter("ids"))) {
            Long[] ids = this.getSelectSids();
            Validation.isTrue(ids != null && ids.length > 0, "至少选择一条记录");
            List<Commodity> commodities = commodityService.findAll(ids);
            for (Commodity commodity : commodities) {
                commodityService.putOff(commodity);
            }
            setModel(OperationResult.buildSuccessResult("下架" + commodities.size() + "条数据"));
        } else {
            commodityService.putOff(bindingEntity);
            setModel(OperationResult.buildSuccessResult("操作成功：下架"));
        }

        return buildDefaultHttpHeaders();
    }

    public HttpHeaders vipCommodityEnable() {
        Long[] ids = this.getSelectSids();
        Validation.isTrue(ids != null && ids.length > 0, "至少选择一条记录");
        List<VipCommodity> vipCommodities = vipCommodityService.findAll(ids);
        for (VipCommodity vipCommodity : vipCommodities) {
            if (Boolean.TRUE.equals(vipCommodity.getEnable())) {
                vipCommodity.setEnable(false);
            } else if (Boolean.FALSE.equals(vipCommodity.getEnable())) {
                vipCommodity.setEnable(true);
            } else {
                vipCommodity.setEnable(true);
            }
            vipCommodityService.save(vipCommodity);
        }
        setModel(OperationResult.buildSuccessResult("启用/停用" + vipCommodities.size() + "条数据"));

        return buildDefaultHttpHeaders();
    }

    /**
     * 将商品过滤枚举转化为 checkbox 的list 值
     * 
     * @return
     */
    public Map<String, String> getSolrFilters() {
        Map<String, String> dataMap = Maps.newHashMap();
        SolrFilterTypeEnum[] solrFilterTypeEnum = SolrFilterTypeEnum.values();
        for (SolrFilterTypeEnum e : solrFilterTypeEnum) {
            MetaData metaData = FieldUtils.getDeclaredField(SolrFilterTypeEnum.class, e.name()).getAnnotation(MetaData.class);
            dataMap.put(e.name(), metaData.value());
        }
        return dataMap;
    }

    @Override
    @MetaData("删除")
    public HttpHeaders doDelete() {
        return super.doDelete();
    }

    public File getErpExcel() {
        return erpExcel;
    }

    public void setErpExcel(File erpExcel) {
        this.erpExcel = erpExcel;
    }
}